package online.flowerinsnow.minecraft.bukkit.testffa.util;

import org.bukkit.Material;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;

import java.util.ArrayList;
import java.util.List;

public class ItemStackFactory implements Cloneable {
    private ItemStack item;

    public ItemStackFactory(Material type) {
        item = new ItemStack(type);
    }

    public ItemStackFactory(Material type, int amount) {
        item = new ItemStack(type, amount);
    }

    public ItemStackFactory(Material type, int amount, short damage) {
        item = new ItemStack(type, amount, damage);
    }

    public ItemStackFactory(Material type, int amount, int damage) {
        this(type, amount, (short) damage);
    }

    public ItemStackFactory(ItemStack item) {
        this.item = item;
    }

    public ItemStackFactory addLore(String lore, boolean color) {
        ItemMeta meta = getMeta();
        List<String> lores = meta.getLore();
        if (lores == null) {
            lores = new ArrayList<>();
        }
        if (color) {
            lores.add(ColorUtils.parseColor(lore));
        } else {
            lores.add(lore);
        }
        setMeta(meta);
        return this;
    }

    public ItemStackFactory addEnchantment(Enchantment enchant, int level, boolean ignoreLevelLimit) {
        ItemMeta meta = getMeta();
        meta.addEnchant(enchant, level, ignoreLevelLimit);
        setMeta(meta);
        return this;
    }

    public ItemStackFactory unbreakable() {
        ItemMeta meta = getMeta();
        meta.spigot().setUnbreakable(true);
//        Class<ItemMeta> classItemMeta = ItemMeta.class;
//        try {
//            Method method = classItemMeta.getDeclaredMethod("setUnbreakable", boolean.class);
//            method.invoke(meta, true);
//        } catch (NoSuchMethodException e) {
//            Class<ItemMeta.Spigot> classItemMetaSpigot = ItemMeta.Spigot.class;
//            try {
//                Method method = classItemMetaSpigot.getDeclaredMethod("setUnbreakable", boolean.class);
//                method.invoke(meta.spigot(), true);
//            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
//                ex.printStackTrace();
//            }
//        } catch (IllegalAccessException | InvocationTargetException e) {
//            e.printStackTrace();
//        }
        setMeta(meta);
        return this;
    }

    public ItemStackFactory breakable() {
        ItemMeta meta = getMeta();
        meta.spigot().setUnbreakable(false);
//        Class<ItemMeta> classItemMeta = ItemMeta.class;
//        try {
//            Method method = classItemMeta.getDeclaredMethod("setUnbreakable", boolean.class);
//            method.invoke(meta, false);
//        } catch (NoSuchMethodException e) {
//            Class<ItemMeta.Spigot> classItemMetaSpigot = ItemMeta.Spigot.class;
//            try {
//                Method method = classItemMetaSpigot.getDeclaredMethod("setUnbreakable", boolean.class);
//                method.invoke(meta.spigot(), false);
//            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException ex) {
//                ex.printStackTrace();
//            }
//        } catch (IllegalAccessException | InvocationTargetException e) {
//            e.printStackTrace();
//        }
        setMeta(meta);
        return this;
    }

    public ItemStackFactory setSkullOwner(String name) throws IllegalStateException {
        SkullMeta meta = (SkullMeta) getMeta();
        meta.setOwner(name);
        setMeta(meta);
        return this;
    }

    public ItemStackFactory setDisplayName(String name, boolean color) {
        ItemMeta meta = getMeta();
        if (color) {
            meta.setDisplayName(ColorUtils.parseColor(name));
        } else {
            meta.setDisplayName(name);
        }
        setMeta(meta);
        return this;
    }

    public ItemStackFactory setLore(List<String> lore) {
        ItemMeta meta = getMeta();
        meta.setLore(lore);
        item.setItemMeta(meta);
        return this;
    }

    public ItemStackFactory addItemFlags(ItemFlag... flags) {
        ItemMeta meta = getMeta();
        meta.addItemFlags(flags);
        item.setItemMeta(meta);
        return this;
    }

    public ItemStack toItemStack() {
        return item;
    }

    private ItemMeta getMeta() {
        return item.getItemMeta();
    }

    private void setMeta(ItemMeta meta) {
        item.setItemMeta(meta);
    }

    /**
     * 复制一份该构建器
     *
     * @return 该构建器的复制体
     */
    @Override
    protected Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }
}